package edu.usc.cmb.iregulome.dao.impl;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.usc.cmb.iregulome.dao.StorageTableDAO;
import edu.usc.cmb.iregulome.entity.Sample;
import edu.usc.cmb.iregulome.entity.Study;

@Transactional
@Service("storageTableDAO")
public class StorageTableDAOImpl implements StorageTableDAO {

	@Autowired
	private SessionFactory sessionFactory;

	private static final ReentrantLock saveSampleLock = new ReentrantLock();

	@Transactional(rollbackFor = { Throwable.class })
	@Override
	public void txSaveSample(Sample sample) {
		Session session = sessionFactory.getCurrentSession();
		saveSampleLock.lock();
		try {
			Sample sam = (Sample) session.get(Sample.class, sample.getId());
			if (sam == null) {
				Study stu = (Study) session.get(Study.class, sample.getStudy()
						.getId());
				if (stu != null) {
					sample.setStudy(stu);
				}
				session.save(sample);
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			saveSampleLock.unlock();
		}
		
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Sample> retrieveDownloadSamples(int downloadMax) {
		List<Sample> result = new LinkedList<Sample>();
		Session session = sessionFactory.getCurrentSession();
		Query q = session
				.createQuery("select count(s) from Sample s where s.downloadFlag = true");
		long alreadyDownNum = (Long) q.list().get(0);
		if (alreadyDownNum >= downloadMax) {
			return result;
		} else {
			Query dq = session
					.createQuery("from Sample s where s.downloadFlag = false and s.taxonid = 9606"
							+ " and (s.study.type = 'RNA-seq' or s.study.type = 'ChIP-seq') ");
			dq.setMaxResults(downloadMax - (int) alreadyDownNum);
			return dq.list();
		}

	}

}
